
#include <BFont>
#include <BPainter>
#include <BProgressBar>
#include "member_BProgressBar.h"

using namespace BWE;

#define member					(*(member_BProgressBar*)_ptr)
#define member_allocate()		_ptr = new member_BProgressBar(this)
#define member_release()		delete (member_BProgressBar*)_ptr

BProgressBar::BProgressBar(BWidget* parent) : BWidget(parent)
{
	member_allocate();
}
BProgressBar::BProgressBar(const BString& format, BWidget* parent) : BWidget(parent)
{
	member_allocate();
	member.format = format;
}
BProgressBar::BProgressBar(Orientation orientation, BWidget* parent) : BWidget(parent)
{
	member_allocate();
	member.orientation = orientation;
}
BProgressBar::BProgressBar(const BString& format, Orientation orientation, BWidget* parent) : BWidget(parent)
{
	member_allocate();
	member.orientation = orientation;
	member.format = format;
}
BProgressBar::~BProgressBar()
{
	member_release();
}

void BProgressBar::setFormat(const BString& format)
{
	if (member.format != format)
	{
		member.format = format;
		member.dirty = true;
		this->fresh();
	}
}
const BString& BProgressBar::format() const
{
	return member.format;
}

const BString& BProgressBar::text() const
{
	return member.text;
}

void BProgressBar::setOrientation(Orientation orientation)
{
	if (member.orientation != orientation)
	{
		member.orientation = orientation;
		this->fresh();
	}
}
Orientation BProgressBar::orientation() const
{
	return member.orientation;
}

void BProgressBar::setValue(int value)
{
	value = member.range.limit(value);
	if (member.value != value)
	{
		member.value = value;
		member.dirty = true;
		emit(Signal_ValueChanged, member.value);
		this->fresh();
	}
}
int BProgressBar::value() const
{
	return member.value;
}

void BProgressBar::setStep(int step)
{
	if (member.step != step)
	{
		member.step = step;
		emit(Signal_StepChanged, member.step);
		this->fresh();
	}
}
int BProgressBar::step() const
{
	return member.step;
}

void BProgressBar::setMinimum(int minimum)
{
	setRange(BRange(minimum, member.range.max()));
}
int BProgressBar::minimum() const
{
	return member.range.min();
}

void BProgressBar::setMaximum(int maximum)
{
	setRange(BRange(member.range.min(), maximum));
}
int BProgressBar::maximum() const
{
	return member.range.max();
}

void BProgressBar::setRange(int minimum, int maximum)
{
	setRange(BRange(minimum, maximum));
}
void BProgressBar::setRange(const BRange& range)
{
	if (member.range != range)
	{
		member.range = range;
		member.dirty = true;
		emit(Signal_RangeChanged, member.range);
		this->fresh();
	}
}
const BRange& BProgressBar::range() const
{
	return member.range;
}

void BProgressBar::increase()
{
	int value = member.value + member.step;
	this->setValue(value);
}
void BProgressBar::decrease()
{
	int value = member.value - member.step;
	this->setValue(value);
}

void BProgressBar::reset()
{
	setValue(member.range.min());
}

const BRect& BProgressBar::chunkRect() const
{
	return member.chunkRect;
}

BSize BProgressBar::sizeHint() const
{
	if (member.dirty)
	{
		member.freshRects();
		member.dirty = false;
	}
	BSize hsize = this->preferSize(member.ia_hintSize);
	return hsize;
}

void BProgressBar::resizeEvent(const BEvent& event)
{
	member.dirty = true;
	this->fresh();
}

void BProgressBar::styleEvent(const BEvent& event)
{
	BWidget::styleEvent(event);
	member.dirty = true;
}
void BProgressBar::freshEvent(const BEvent& event)
{
	if (member.dirty)
	{
		member.freshRects();
		member.dirty = false;
	}
}
void BProgressBar::paintEvent(const BEvent& event)
{
	BWidget::paintEvent(event);

	BPainter painter(this);

	painter.setColor(Color_Chunk);
	painter.fillRect(member.chunkRect);

	if (member.image && member.ia_imageRect.valid())
	{
		painter.drawImage(member.ia_imageRect, member.image);
	}
	painter.setColor(Color_Text);
	painter.drawText(member.ia_textRect, member.text);
}
